package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.cache.key.RedisKey;
import cn.wolfcode.luowowo.cache.service.IStrategyStatsCacheService;
import cn.wolfcode.luowowo.cache.vo.StrategyStats;
import cn.wolfcode.luowowo.common.util.DateUtil;
import com.alibaba.fastjson.JSON;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class StrategyStatsCacheServiceImpl implements IStrategyStatsCacheService {

    @Autowired
    private StringRedisTemplate template;
    @Override
    public void setStrategyStats(StrategyStats vo) {
        String cacheKey = RedisKey.STRATEGY_STATS.getCacheKey(vo.getStrategyId());
        template.opsForValue().set(cacheKey, JSON.toJSONString(vo));
    }

    @Override
    public boolean hasStatsKey(Long strategyId) {
        String cacheKey = RedisKey.STRATEGY_STATS.getCacheKey(strategyId);
        return template.hasKey(cacheKey);
    }

    @Override
    public StrategyStats getStrategyStats(Long strategyId) {
        String cacheKey = RedisKey.STRATEGY_STATS.getCacheKey(strategyId);
        String json = template.opsForValue().get(cacheKey);
        return JSON.parseObject(json,StrategyStats.class);
    }

    @Override
    public void incrNum(Long strategyId, int num, int type) {
        //根据id查询文章
        StrategyStats vo = getStrategyStats(strategyId);
        //很久类型偏移值
        switch (type){
            case STRATEGY_STATS_VIEWNUM :
                vo.setViewnum(vo.getViewnum() + num);
                break;

            case STRATEGY_STATS_REPLYNUM :
                vo.setReplynum(vo.getReplynum() + num);
                break;
            case  STRATEGY_STATS_FAVORNUM :
                vo.setFavornum(vo.getFavornum() + num);
                break;
            case  STRATEGY_STATS_THUMBSUPNUM :
                vo.setThumbsupnum(vo.getThumbsupnum() + num);
                break;
            case  STRATEGY_STATS_SHARENUM :
                vo.setSharenum(vo.getSharenum() + num);
                break;
        }
        setStrategyStats(vo);
    }

    @Override
    public boolean favor(Long strategyId, Long userId) {
        boolean flag = true;
        ValueOperations<String, String> op = template.opsForValue();
        //获取文章的所有收藏者在redis中的key
        String cacheKey = RedisKey.STRATEGY_STATS_FAVOR.getCacheKey(strategyId);
        //获取用户收藏游记的key
        String userStrategyCacheKey = RedisKey.USER_STRATEGY.getCacheKey(userId);
        //strategies 所有游记的id
        List<Long> strategies = new ArrayList<>();
        //user,所有收藏者的id
        List<Long> users = new ArrayList<>();
        //num:偏移值
        int num = 0;

        //判断是否被收藏过,有查询redis中的收藏攻略
        if (template.hasKey(userStrategyCacheKey)){
            String json = op.get(userStrategyCacheKey);
            strategies =JSON.parseArray(json,Long.class);
        }

        //判断是否有被收藏过
        if (template.hasKey(cacheKey)){//有被收藏
            //查询redis中的收藏者
            String vo = op.get(cacheKey);
            //将字符串数据解析成Long类型的数据
            users = JSON.parseArray(vo,Long.class);
            //判断users中是否已有当前登录用户
            if (users.contains(userId)){
                //取消收藏
                users.remove(userId);
                strategies.remove(strategyId);
                num = -1;
                flag = false;
            }else {
                //收藏
                users.add(userId);
                strategies.add(strategyId);
                num = 1;
            }
        }else{//文章第一次被收藏
            //将当前登录用户id加入list集合
            users.add(userId);
            strategies.add(strategyId);
            num = 1;
        }
        //将users存进redis
        op.set(cacheKey,JSON.toJSONString(users));
        //将strategies存进redis
        op.set(userStrategyCacheKey,JSON.toJSONString(strategies));
        //更新收藏数据
        incrNum(strategyId,num,STRATEGY_STATS_FAVORNUM);
        return flag;
    }

    @Override
    public boolean isFavor(Long strategyId, Long userId) {
        String cacheKey = RedisKey.STRATEGY_STATS_FAVOR.getCacheKey(strategyId);
        String vo = template.opsForValue().get(cacheKey);
        if (vo != null){
            List<Long> users = JSON.parseArray(vo,Long.class);
            return users.contains(userId);
        }
       return false;
    }

    @Override
    public boolean strategyThumbup(Long strategyId, Long userId) {
        boolean flag = false;
        //判断当前攻略在缓存在是否有key
        String  key = strategyId.toString() + ":" + userId.toString();
        String cacheKey = RedisKey.STRATEGY_STATS_THUMBUP.getCacheKey(key);
        if(!template.hasKey(cacheKey)){//没有顶过
            Date now = new Date();
            Date endDate = DateUtil.getEndDate(now);
            //往redis中存入key
            template.opsForValue().set(cacheKey,"", DateUtil.getDateBetween(now,endDate), TimeUnit.MILLISECONDS);
            //文章收藏数加1
            incrNum(strategyId,1,IStrategyStatsCacheService.STRATEGY_STATS_THUMBSUPNUM);
            flag = true;
        }
        return flag;
    }

    @Override
    public List<StrategyStats> listAllStrateg() {
        ValueOperations<String, String> op = template.opsForValue();
        List<StrategyStats> vos = new ArrayList<>();
        //根据前缀获取key的集合
        String cacheKey = RedisKey.STRATEGY_STATS.getCacheKey("*");
        Set<String> keys = template.keys(cacheKey);
        //遍历,将文章数据存进vos
        for (String key : keys) {
            //获取文章数据
            String vo = op.get(key);
            vos.add(JSON.parseObject(vo,StrategyStats.class));
        }
        return vos;
    }

    @Override
    public void addScore(RedisKey key, int num, Long detailId) {
        String value = RedisKey.STRATEGY_STATS.getCacheKey(detailId);
        template.opsForZSet().incrementScore(key.getPrefix(),value,num);
    }


    @Override
    public boolean exist(RedisKey key, Long detailId) {
        String value = RedisKey.STRATEGY_STATS.getCacheKey(detailId);
        Long rank = template.opsForZSet().rank(key.getPrefix(), value);  //升序返回排名,如果不存在则为null
        return rank == null;
    }

    @Override
    public List<StrategyStats> listCommends(RedisKey key) {
        List<StrategyStats> list = new ArrayList<>();
        ValueOperations<String, String> op = template.opsForValue();
        // 降序排名
        Set<String> set = template.opsForZSet().reverseRange(key.getPrefix(), 0, 9);
        for (String s : set) {
            String vo = op.get(s);
            list.add(JSON.parseObject(vo,StrategyStats.class));
        }
        return list;
    }

    @Override
    public List<Long> listStrategiesByUserId(Long userId) {
        String cacheKey = RedisKey.USER_STRATEGY.getCacheKey(userId);
        String json = template.opsForValue().get(cacheKey);
        return  JSON.parseArray(json,Long.class);
    }

    /*@Override
    public boolean setTravelByUserId(Long travelId, Long userId) {
        boolean flag = true;
        ValueOperations<String, String> op = template.opsForValue();
        //获取用户收藏游记的key
        String cacheKey = RedisKey.USER_TRAVEL.getCacheKey(userId);
        //user,所有游记的id
        List<Long> travels = new ArrayList<>();
        //判断是否有被收藏过
        if (template.hasKey(cacheKey)){//有被收藏
            //查询redis中的收藏者
            String vo = op.get(cacheKey);
            //将字符串数据解析成Long类型的数据
            travels = JSON.parseArray(vo,Long.class);
            //判断users中是否已有当前登录用户
            if (travels.contains(travelId)){
                //取消收藏
                travels.remove(travelId);
                flag = false;
            }else {
                //收藏
                travels.add(travelId);
            }
        }else{//文章第一次被收藏
            //将当前登录游记id加入list集合
            travels.add(travelId);
        }
        //将travels存进redis
        op.set(cacheKey,JSON.toJSONString(travels));
        return flag;
    }*/
}
